package com.streambolics.std;

public abstract class Visitor<T>
{
    /**
     * Begins the visit. This method is called once, at the beginning of the
     * visit.
     * 
     * @throws Exception
     *             Any exception thrown by the beginVisit will abort the visit.
     *             endVisit() will not be called.
     */

    protected void beginVisit () throws Exception
    {
    }

    /**
     * Ends the visit. This method is called once when all items have been
     * visited, or as soon as one visit results in an exception being thrown.
     * 
     * endVisit is not called if beginVisit threw an exception.
     * 
     * @throws Exception
     */

    protected void endVisit () throws Exception
    {
    }

    /**
     * Visits all values once. beginVisit is called before any other value,
     * endVisit is called after all values have been visited.
     * 
     * Visit is aborted early if any call to visit() throws an exception.
     * 
     * @param values
     *            The list of values to visit.
     * 
     * @throws Exception
     */

    public void visit (Iterable<T> values) throws Exception
    {
        beginVisit ();
        try
        {
            for (T t : values)
            {
                visit (t);
            }
        }
        finally
        {
            endVisit ();
        }
    }

    protected abstract void visit (T value) throws Exception;
}
